// locutor command line client
// (c) 2009, Normen Müller, normen.mueller@gmail.com  
// $Id: Locutor.scala 74 2010-05-07 21:01:48Z normen.mueller $
package locutor.draft.demo

import java.io.File

import scaup.Views._

import scalaxx.diff._

/** A Change Impact Analysis workflow demonstation powered by locutor.
 * 
 * @todo ad hoc document type specific configurations, i.e. mapping of MIME/ DTD/ Document to a configuration
 *       comprising an equivalence specification, a graph model, and a rule system.  User annotations extending
 *       the computed dependency graph are optional.
 * 
 * @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 * @version 0.0.4 */
//object Locutor { 
//  
//  def main(args: Array[String]) {
//    // === Initialize system environment
//    initialize
//    
//    // === Create a collection of documents C whereas each document Doc has an associated document model M. For each document Doc within a document collection C, the associated graph model G
//    // === is extended by the structural node types N_syn and structural link types L_syn of Doc, such that M(Doc) = <E, G join (N_syn, L_syn), R>.
//    val C = DocumentCollection("wedding",
//      ("etc/data/wedding/guests.xml", DocumentModel("wedding/guests.eq", "wedding/guests.gm", "wedding/guests.rs")),
//      ("etc/data/wedding/seating.xml", DocumentModel("wedding/seating.eq", "wedding/seating.gm", "wedding/seating.rs")))    
//    // === Flush associated document models and verify if flushed output is adequate, i.e. parsing the flushed output again must not result in parsing errors.  Note that already during creation
//    // ==  of a document collection existence of respective documents is verified.
//    validate(C)    
//    
//    // === Simulate a change
//    // v1: modification: list of invited guests permuted | deltas: empty | effects: none
//    "etc/data/wedding/guestsv1.xml".toFile copyTo "etc/data/wedding/guests.xml".toFile
//    
//    // === Semantic difference analysis
//    val Δ = C.analyze    
//    // === Flush identified differences
//    flush(Δ)
//        
//    // === Semantic dependency analysis
//    // === For each document within the document collection the dependency graph is computed comprising structural as well as semanitc nodes and links.  In addition one can add ``manual''
//    // === annotations, i.e. not inferrable annotations.
//    implicit val D = C.annotate /*(
//      ("etc/data/wedding/guests.xml", "guests-exttannos.grs"),
//      ("etc/data/wedding/seating.xml", "seating-exttannos.grs")
//    )*/    
//    // === Flush dependency graphs and verify if flushed output is adequate.
//    validate(D)
//    
//    // === Change impact analysis
//    // === Note the for using ``↩'' a semantic dependency analysis has to be implicitly given.  Otherwise use ``ripple'' explicitly, like C.ripple(D, Δ).
////    val I = C ↩ Δ
//    
//    // === Revert simulated change
//    // v1: list of invited guests permuted -> No change
//    "etc/data/wedding/guestsv0.xml".toFile copyTo "etc/data/wedding/guests.xml".toFile
//  }
//  
//  /* System configuration
//   * @todo Externalize to XML configuration file */
//  def initialize = {
//    System.setProperty("locutor.tmp",   "/Users/nmueller/tmp/locutor")  // temporary directory
//    System.setProperty("locutor.grgen", "/opt/grgen/bin")               // GrGen home directory
//    System.setProperty("locutor.equiv", "etc/kb/eq")                    // Knowledge base | Equivalence Specifications
//    System.setProperty("locutor.types", "etc/kb/gm")                    // Knowledge base | Graph Models
//    System.setProperty("locutor.rules", "etc/kb/rs")                    // Knowledge base | Rule Systems
//  }
//  
//  def validate(collection: DocumentCollection) {
//    collection foreach (_ match { case (document, model) =>
//      try {
//        println("validating document model of \""+document.name+"\"")
//        print("... equivalence system")
//        scalaxx.diff.EquivalenceSystem.parse(model.equivSys.toString)
//        model.equivSys.toString >>> (System.getProperty("locutor.tmp").toFile / (document.label + ".eq"))
//        println(" ok")
//      } catch {
//        case e:Exception =>
//          println("Equivalence Specification validation error.")
//          throw e
//      }        
//      try {
//        print("... graph model (1)")
//        GraphModel.parse("model V { " + model.graphModel.toGrGen + "}")
//        println("    ok")
//        print("... graph model (2)")
//        GrGen.validate(model.graphModel)
//        println("    ok")
//      } catch {
//        case e:Exception =>
//          println("Graph Model validation error.")
//          throw e
//      }
//    })    
//  }
//  
//  def validate(dependencies: Map[File, DependencyGraph]) =
//    dependencies foreach (_ match { case (document, graph) =>
//      try {
//        println("validating dependency graph of \""+document.name+"\"")
//        print("... dependency graph")
//        GrGen.validate(graph)
//        println("    ok")
//      } catch {
//        case e:Exception =>
//          println("Dependency Graph validation error.")
//          throw e
//      }                       
//    })
//  
//  def flush(infos: Map[File, _]) {
//    for(info <- infos) info match {
//      case (document, commands: List[_])      => (commands mkString "\n") >>> (System.getProperty("locutor.tmp").toFile / (document.label + ".diff"))
//      case (document, graph: DependencyGraph) => graph.toGrShell >>> (System.getProperty("locutor.tmp").toFile / (document.label + ".dep"))
//    }
//  }
//  
//}

//object LocutorTst {
//  
//  def main(args: Array[String]) {
//    
//    // config
//    System.setProperty("locutor.tmp",    "/Users/nmueller/tmp/locutor")
//    System.setProperty("locutor.grgen",  "/opt/grgen/bin")
//    System.setProperty("locutor.equivs", "etc/kb/eq")
//    System.setProperty("locutor.models", "etc/kb/gm")
//    System.setProperty("locutor.rules",  "etc/kb/rs")
//    
//    val LOCUTOR_EQUIVS = System.getProperty("locutor.equivs").toFile
//    val LOCUTOR_RULES  = System.getProperty("locutor.rules").toFile
//    
//    val orgFile = "etc/data/svnbook/svnbook.xml".toFile
//    
//    // ---------------------------------------------------
//    // ``<preface id="svn.foreword">'' removed    
//    val modFile = "etc/data/svnbook/svnbook-v1.xml".toFile
//    
//    // ``<preface id="svn.foreword">'' removed
//    // ``<indexterm>'' removed
//    //val modFile = "etc/data/svnbook/svnbook-v2.xml".toFile
//    // ---------------------------------------------------
//
//    // parameters
//    val args = Array[String](
//      "etc/data/svnbook/svnbook.dg",        // dependency graph
//      (LOCUTOR_EQUIVS / "svnbook.eq").path, // equivalence system
//      (LOCUTOR_RULES / "svnbook.rs").path,  // rule system
//      orgFile.path,                         // old file
//      modFile.path                          // modified file
//    )
//      
//    locutor.cli.Locutor.main(args)
//                                                              
//enum CT {none, removed, reordered, renamed, rephrased}
//enum DT {ident, name, position, literal, size, url}
//abstract directed edge class Dependency connect Infom --> Infom { via: set<string> = { "ident" }; }
//edge class dependsOn extends Dependency connect Infom --> Infom[+];
// directed:
//edge class dependsOn extends Dependency connect Infom[+] --> Infom[+];
//edge class requiredBy extends Dependency connect Infom[+] --> Infom[+];
// undirected:
//edge class correlatesWith extends Dependency connect Infom[+] --> Infom[+];
//
//  }
//
//}